<template>
  <div>
    <AForm :model="searchFrom" class="erp-search-form">
      <ARow class="grid-demo" :gutter="10">
        <ACol :span="6">
          <AFormItem hide-label content-class="">
            <AInput v-model="searchFrom.saleOrderCode" placeholder="订单编号" />
          </AFormItem>
        </ACol>
        <ACol :span="6">
          <AFormItem hide-label content-class="">
            <AInput v-model="searchFrom.productName" placeholder="产品名称" />
          </AFormItem>
        </ACol>
        <ACol :span="6">
          <AFormItem hide-label content-class="">
            <AInput v-model="searchFrom.prodFlowCode" placeholder="生产流程编号" />
          </AFormItem>
        </ACol>
        <ACol :span="6">
          <AFormItem hide-label content-class="">
            <ARangePicker
              v-model="searchFrom.deliveryDate"
              :placeholder="['交货日期', '交货日期']"
            />
          </AFormItem>
        </ACol>
      </ARow>
    </AForm>
    <ACard>
      <div class="erp-mb-10 w100 erp-search-btn-box">
        <ASpace>
          <AButton type="primary" @click="onSearch">
            <template #icon>
              <icon-search />
            </template>
          </AButton>
          <ATooltip content="清空筛选项" position="top">
            <AButton type="dashed" @click="onReset">
              <template #icon>
                <icon-refresh />
              </template>
            </AButton>
          </ATooltip>
          <AButton v-if="isAuth([1, 2])" type="outline" @click="openEdit('新增')">新增</AButton>
          <AButton
            v-if="isAuth([1, 2])"
            type="outline"
            :disabled="isEmpty(planList)"
            @click="outFinish()"
          >
            提交至生产完成
          </AButton>
          <ATooltip
            v-if="isAuth([1, 2])"
            content="请选择未出库的数据"
            position="top"
            :disabled="!(isEmpty(selectRows) || !!selectRows.find((item) => item.outboundStatus))"
          >
            <AButton
              type="outline"
              :disabled="isEmpty(selectRows) || !!selectRows.find((item) => item.outboundStatus)"
              :loading="outWarehouseLoad"
              @click="outWarehouse()"
            >
              原材料出库
            </AButton>
          </ATooltip>
          <ATooltip v-if="isAuth([1, 2])" :disabled="!isEmpty(selectRows)" content="请选择数据">
            <AButton status="danger" @click="batchDel()">批量删除</AButton>
          </ATooltip>
        </ASpace>
        <ASpace>
          <AButton type="primary" @click="onExport('table')">导出</AButton>
        </ASpace>
      </div>
      <ATable
        ref="tableRef"
        :pagination="false"
        :data="tableData"
        :bordered="{ cell: true }"
        :row-selection="{ showCheckedAll: true, type: 'checkbox' }"
        :span-method="spanMethod"
        span-all
        column-resizable
        row-key="prodPlanDetailId"
        size="small"
        @select="
          (rowKeys: (string | number)[], rowKey: string | number, record: TableData) =>
            tableEvent('select', { rowKeys, rowKey, record })
        "
        @select-all="(checked: boolean) => tableEvent('select-all', checked)"
      >
        <template #columns>
          <ATableColumn title="创建日期" data-index="createdDt" :width="100">
            <template #cell="{ record }">
              <div>{{ dayjs(record.createdDt).format('YYYY-MM-DD') }}</div>
            </template>
          </ATableColumn>
          <ATableColumn title="生产计划">
            <ATableColumn title="生产计划编号" data-index="prodPlanCode" :width="100">
            </ATableColumn>
            <ATableColumn title="产品名称" data-index="productName" :width="100"></ATableColumn>
            <ATableColumn title="规格型号" data-index="specModel" :width="100"></ATableColumn>
            <ATableColumn title="单位" data-index="unit" :width="100"></ATableColumn>
            <ATableColumn title="数量" data-index="qty" :width="100"></ATableColumn>
            <ATableColumn title="工序内容" data-index="processContent" :width="100">
              <template #cell="{ record }">
                <div v-if="!isEmpty(record.processNameList)">
                  {{ record.processNameList.join(',') }}
                </div>
              </template>
            </ATableColumn>
            <ATableColumn title="交货日期" data-index="deliveryDate" :width="100">
              <template #cell="{ record }">
                <div v-if="record.deliveryDate">
                  {{ dayjs(record.deliveryDate).format('YYYY-MM-DD') }}
                </div>
              </template>
            </ATableColumn>
          </ATableColumn>
          <ATableColumn title="原材料信息">
            <ATableColumn title="材料名称" data-index="material.materialName" :width="100">
            </ATableColumn>
            <ATableColumn title="规格型号" data-index="material.spec" :width="100"></ATableColumn>
            <ATableColumn title="单位" data-index="material.unit" :width="100"></ATableColumn>
            <ATableColumn title="数量" data-index="material.qty" :width="100"></ATableColumn>
            <ATableColumn title="材质代码" data-index="material.materialCode" :width="100">
            </ATableColumn>
            <ATableColumn
              title="出库"
              data-index="material.outboundStatus"
              :width="70"
              align="center"
            >
              <template #cell="{ record }">
                <icon-check-circle-fill
                  v-if="record.material.outboundStatus"
                  style="color: #67c23a"
                  size="20px"
                />
                <icon-close-circle-fill
                  v-if="!record.material.outboundStatus"
                  style="color: red"
                  size="20px"
                />
              </template>
            </ATableColumn>
          </ATableColumn>
          <ATableColumn title="备注" data-index="remark" :width="100"></ATableColumn>
          <ATableColumn v-if="isAuth([1, 2])" title="操作" :width="150" fixed="right">
            <template #cell="{ record }">
              <ASpace>
                <AButton type="primary" size="mini" @click="rowEvent(record, 'edit')">
                  修改
                </AButton>
                <AButton type="primary" size="mini" @click="rowEvent(record, 'print')">
                  打印
                </AButton>
              </ASpace>
              <ASpace class="erp-mt-6">
                <AButton type="primary" size="mini" @click="rowEvent(record, 'copy')">
                  复制
                </AButton>
                <AButton status="danger" size="mini" @click="rowEvent(record, 'del')">
                  删除
                </AButton>
              </ASpace>
            </template>
          </ATableColumn>
        </template>
      </ATable>
      <div class="arco-table-pagination">
        <APagination
          :total="pageParam.totalCount"
          :page-size="pageParam.pageSize"
          show-total
          @change="(page: number) => tableEvent('page-change', page)"
        />
      </div>
    </ACard>
    <EditPopupForm
      v-model:visible="editModal"
      :title="editModalTitle"
      :check-data="rowData"
      @reload="
        () => {
          getTableData()
          clearTableSelect()
        }
      "
    ></EditPopupForm>
    <materialPrint ref="materialPrintRef" :check-data="detailData"></materialPrint>
    <batchAddProductionFinish
      v-model:visible="productionFinish"
      title="新增生产完成"
      :check-data="planList"
      @reload="
        () => {
          getTableData()
          clearTableSelect()
        }
      "
    ></batchAddProductionFinish>
  </div>
</template>

<script lang="ts" setup>
import EditPopupForm from './editPopupForm.vue'
import materialPrint from './print.vue'
import dayjs from 'dayjs'
import { Message, Modal, TableData, TableInstance } from '@arco-design/web-vue'
import {
  batchDelProdPlan,
  delProductionPlan,
  getProductionPlanAllList,
  getProductionPlanDetail,
  getProductionPlanPageList,
  HandleProductionPlanResItem,
  materialOutWarehouse,
  materialOutWarehouseReq,
  ProductionPlanListSearch,
  ProductionPlanResItem
} from '@renderer/api/productionDep'
import batchAddProductionFinish from './batchAddProductionFinish.vue'
import { isEmpty, uniqBy } from 'lodash-es'
import { isAuth } from '@renderer/utils/auth'

const searchFrom = ref<ProductionPlanListSearch>({
  deliveryDate: []
})
const editModal = ref(false)
const editModalTitle = ref('新增')
const tableData = ref<HandleProductionPlanResItem[]>([])
const pageParam = reactive({
  currentPage: 1,
  pageSize: 20,
  totalCount: 0
})
const materialPrintRef = ref<InstanceType<typeof materialPrint>>() // 打印组件
const detailData = ref<ProductionPlanResItem>({
  productName: '',
  unit: '',
  prodFlowCode: [],
  planProdQty: 0,
  deliveryDate: '',
  remark: '',
  createdBy: '',
  createdDt: '',
  updatedBy: '',
  updatedDt: '',
  prodPlanId: '',
  saleOrderId: '',
  saleOrderCode: '',
  productId: '',
  detailList: [],
  prodPlanCode: '',
  spec: '',
  processIdList: [],
  productCategory: '',
  specModel: '',
  materialName: '',
  materialCode: '',
  materialDesc: '',
  fluteType: '',
  crimpLine: '',
  processNameList: [],
  qty: 0
})
const outWarehouseLoad = ref(false)
const selectRows = ref<HandleProductionPlanResItem['detailList']>([])
const productionFinish = ref(false)
const planList = ref<HandleProductionPlanResItem[]>([])
const tableRef = ref<TableInstance>()

onMounted(() => {
  getTableData()
})

function formatData(baseData: ProductionPlanResItem[]): HandleProductionPlanResItem[] {
  return baseData
    .map((item, index) => {
      item.index = index + 1
      if (!isEmpty(item.detailList)) {
        return item.detailList.map((detailItem, index) => {
          if (index === 0) {
            return {
              material: { ...detailItem },
              ...item,
              span: item.detailList.length,
              prodPlanDetailId: detailItem.prodPlanDetailId
            }
          } else {
            return {
              material: { ...detailItem },
              ...item,
              prodPlanDetailId: detailItem.prodPlanDetailId
            }
          }
        })
      } else {
        return [{ ...item, material: {} }]
      }
    })
    .flat()
}

async function getTableData() {
  const [deliveryStartDate, deliveryEndDate] = searchFrom.value.deliveryDate! || []
  searchFrom.value.deliveryStartDate = deliveryStartDate
    ? dayjs(deliveryStartDate).format('YYYY-MM-DD')
    : ''
  searchFrom.value.deliveryEndDate = deliveryEndDate
    ? dayjs(deliveryEndDate).format('YYYY-MM-DD')
    : ''
  const res = await getProductionPlanPageList({ ...searchFrom.value, ...pageParam })
  tableData.value = formatData(res.data.list)
  pageParam.totalCount = res.data.totalCount!
}

const spanMethod = ({ record, columnIndex }) => {
  if (columnIndex < 9 || columnIndex > 14) {
    if (record.span) {
      return {
        colspan: 1,
        rowspan: record.span
      }
    }
  }
}

function clearTableSelect() {
  tableRef.value?.selectAll(false)
  selectRows.value = []
  planList.value = []
}

const onSearch = () => {
  pageParam.currentPage = 1
  getTableData()
}

function onReset() {
  searchFrom.value = {
    deliveryDate: []
  }
  pageParam.currentPage = 1
  pageParam.pageSize = 20
  getTableData()
}

function batchDel() {
  const idList = selectRows.value.map((item) => item.prodPlanId)
  batchDelProdPlan({ idList: idList }).then(() => {
    Message.success('删除成功')
    onSearch()
    clearTableSelect()
  })
}

function tableEvent(type: 'page-change' | 'select' | 'select-all', param: any) {
  switch (type) {
    case 'page-change':
      pageParam.currentPage = param
      getTableData()
      break
    case 'select':
      {
        const { rowKeys, rowKey, record } = param
        if (rowKeys.includes(rowKey)) {
          selectRows.value = selectRows.value.concat(record.detailList)
          planList.value.push(record)
          // 判断是否全选
          const tempIDs = planList.value.map((item) => item.prodPlanId)
          if (tableData.value.every((item) => tempIDs.includes(item.prodPlanId))) {
            tableRef.value.selectAll(true)
          }
        } else {
          selectRows.value = selectRows.value.filter((item) => item.prodPlanId != record.prodPlanId)
          planList.value = planList.value.filter((item) => item.prodPlanId != record.prodPlanId)
        }
      }
      break
    case 'select-all':
      if (param) {
        const temp: HandleProductionPlanResItem['detailList'] = tableData.value.flatMap(
          (item) => item.detailList
        )
        selectRows.value = selectRows.value.concat(temp)
        planList.value = planList.value.concat(tableData.value)
        planList.value = uniqBy(planList.value, 'prodPlanId')
      } else {
        const ids = tableData.value.map((item) => item.prodPlanId)
        selectRows.value = selectRows.value.filter((item) => !ids.includes(item.prodPlanId))
        planList.value = planList.value.filter((item) => !ids.includes(item.prodPlanId))
      }
      break

    default:
      break
  }
}

function openEdit(title: string) {
  rowData.value = {}
  editModalTitle.value = title
  editModal.value = true
}

const rowData = ref<Partial<ProductionPlanResItem>>({})

function rowEvent(row: ProductionPlanResItem, type: 'del' | 'copy' | 'edit' | 'print') {
  switch (type) {
    case 'del':
      Modal.warning({
        title: '警告',
        content: '当前数据删除后不可恢复，是否继续？',
        okText: '确认',
        cancelText: '取消',
        simple: false,
        hideCancel: false,
        maskClosable: false,
        closable: false,
        onOk: () => {
          delProductionPlan({ prodPlanId: row.prodPlanId! }).then(() => {
            Message.success('删除成功')
            getTableData()
          })
        },
        onCancel: () => {}
      })
      break
    case 'copy':
      rowData.value = row
      editModalTitle.value = '复制'
      editModal.value = true
      break
    case 'edit':
      rowData.value = row
      editModalTitle.value = '修改'
      editModal.value = true
      break
    case 'print':
      getProductionPlanDetail({ prodPlanId: row.prodPlanId }).then((res) => {
        detailData.value = res.data
        nextTick(() => {
          materialPrintRef.value?.printInfo()
        })
      })
      break

    default:
      break
  }
}

async function onExport(type: 'table' | 'template') {
  let fileTitle: string
  const headerData = [
    { title: '创建时间', value: 'createdDt', width: 180 },
    { title: '生产计划编号', value: 'prodPlanCode', width: 180 },
    { title: '产品名称', value: 'productName', width: 180 },
    { title: '规格型号', value: 'specModel', width: 180 },
    { title: '单位', value: 'unit', width: 180 },
    { title: '数量', value: 'qty', width: 180 },
    { title: '工序内容', value: 'processNames', width: 180 },
    { title: '交货日期', value: 'deliveryDate', width: 180 },
    { title: '材料名称', value: 'material.materialName', width: 180 },
    { title: '规格型号', value: 'material.spec', width: 180 },
    { title: '单位', value: 'material.unit', width: 180 },
    { title: '数量', value: 'material.qty', width: 180 },
    { title: '材质代码', value: 'material.materialCode', width: 180 },
    { title: '出库', value: 'material.outboundStatus', width: 180 },
    { title: '备注', value: 'remark', width: 180 }
  ]
  let excelData: HandleProductionPlanResItem[] = []
  switch (type) {
    case 'table':
      {
        fileTitle = '生产计划数据'
        headerData.unshift({ title: '序号', value: 'index', width: 80 })
        const res = await getProductionPlanAllList(searchFrom.value)
        excelData = formatData(res.data.list)
        excelData = excelData.map((item) => {
          item.processNames = item.processNameList?.join(',')
          item.material!.outboundStatus = item.material?.outboundStatus ? '是' : '否'
          return item
        })
      }
      break
    case 'template':
      fileTitle = '生产计划导入模板'
      excelData = [
        {
          prodPlanId: '',
          prodPlanCode: '',
          saleOrderId: '',
          saleOrderCode: '',
          productId: '',
          productName: '',
          spec: '',
          unit: '',
          planProdQty: 0,
          processIdList: [],
          deliveryDate: '',
          remark: '',
          productCategory: '',
          specModel: '',
          materialName: '',
          materialCode: '',
          materialDesc: '',
          fluteType: '',
          crimpLine: '',
          processNameList: [],
          createdBy: '',
          createdDt: '',
          updatedBy: '',
          updatedDt: '',
          qty: 0,
          prodFlowCode: [],
          detailList: []
        }
      ]
      break
    default:
      break
  }
  import('@renderer/utils/vendor').then((excel) => {
    excel.exportExcel(excelData, headerData, fileTitle)
  })
}

const outFinish = () => {
  productionFinish.value = true
}

const outWarehouse = () => {
  if (isEmpty(selectRows.value)) return
  Modal.warning({
    title: '提醒',
    content: '是否确认出库',
    okText: '确认',
    cancelText: '取消',
    simple: false,
    hideCancel: false,
    maskClosable: false,
    closable: false,
    onOk: () => {
      outWarehouseLoad.value = true

      const params: materialOutWarehouseReq[] = selectRows.value.map((item) => {
        return {
          materialStockId: item!.materialStockId,
          stockQty: item!.qty,
          prodPlanDetailId: item!.prodPlanDetailId
        }
      })
      materialOutWarehouse(params)
        .then(() => {
          Message.success('出库成功')
          getTableData()
          clearTableSelect()
        })
        .finally(() => {
          outWarehouseLoad.value = false
        })
    },
    onCancel: () => {}
  })
}
</script>
<style lang="less" scoped>
.erp-search-btn-box {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
